package org.lemon.cla.controller;

import com.baomidou.mybatisplus.core.metadata.IPage; // 导入 IPage
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content; // 导入 Content
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.lemon.cla.enums.HttpStatusEnum;
import org.lemon.cla.dto.response.ResponseResult;
import org.lemon.cla.dto.request.CanteenMenuCreateRequest;
import org.lemon.cla.dto.request.CanteenMenuUpdateRequest;
import org.lemon.cla.dto.request.CanteenMenuSearchRequest; // 导入新的查询DTO
import org.lemon.cla.pojo.CanteenMenu;
import org.lemon.cla.enums.WeekdayEnum; // WeekdayEnum 依然需要，用于 WeekdayEnumConverter
import org.lemon.cla.service.ICanteenMenuService;
import org.springframework.beans.BeanUtils; // 用于属性拷贝
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid; // 导入 jakarta.validation.Valid

import java.util.List; // 尽管不再直接返回List，但可能因其他业务逻辑或遗留代码保留
import java.util.Optional; // 导入Optional

import org.lemon.cla.exception.BusinessException; // 导入自定义业务异常


@RestController
@RequestMapping("/api/canteen-menus")
@Tag(name = "食堂菜单管理", description = "提供食堂菜单信息的 CRUD 和查询接口")
public class CanteenMenuController {

    @Autowired
    private ICanteenMenuService canteenMenuService;

    @Operation(summary = "分页查询食堂菜单", description = "根据条件分页获取食堂菜单列表。查询条件通过请求体传递，可按食堂名称或星期筛选。")
    @PostMapping("/search") // 更改为 POST 方法，并为搜索功能添加明确的路径
    public ResponseResult<IPage<CanteenMenu>> searchCanteenMenus(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") Integer pageSize,
            // 更改为 @RequestBody 接收 DTO
            @io.swagger.v3.oas.annotations.parameters.RequestBody( // OpenAPI 文档注解
                    description = "食堂菜单查询请求对象 (可选，用于筛选)",
                    required = false,
                    content = @Content(schema = @Schema(implementation = CanteenMenuSearchRequest.class))
            ) @org.springframework.web.bind.annotation.RequestBody CanteenMenuSearchRequest request) { // Spring MVC 的 @RequestBody

        Page<CanteenMenu> page = new Page<>(pageNum, pageSize);

        // 使用Optional简化，确保request总是一个非null的实例
        request = Optional.ofNullable(request).orElseGet(CanteenMenuSearchRequest::new);

        IPage<CanteenMenu> menuPage = canteenMenuService.searchCanteenMenusByConditions(page, request);
        return ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), menuPage);
    }

    @Operation(summary = "获取所有食堂菜单", description = "分页获取所有食堂菜单列表（不带任何筛选条件）。")
    @GetMapping // 保留一个简单的GET /api/canteen-menus，用于获取所有（无筛选）的分页列表
    public ResponseResult<IPage<CanteenMenu>> getAllCanteenMenus(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10") Integer pageSize) {
        Page<CanteenMenu> page = new Page<>(pageNum, pageSize);
        // 调用统一的搜索方法，传入空的请求对象，表示无筛选
        IPage<CanteenMenu> menuPage = canteenMenuService.searchCanteenMenusByConditions(page, new CanteenMenuSearchRequest());
        return ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), menuPage);
    }


    @Operation(summary = "根据ID获取食堂菜单", description = "根据菜单ID获取食堂菜单详情。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "成功获取菜单"),
            @ApiResponse(responseCode = "404", description = "菜单未找到")
    })
    @GetMapping("/{id}")
    public ResponseResult<CanteenMenu> getCanteenMenuById(
            @Parameter(description = "菜单ID", required = true, example = "1") @PathVariable Long id) {
        // 使用Optional简化null检查，如果未找到则抛出业务异常
        return Optional.ofNullable(canteenMenuService.getById(id))
                .map(menu -> ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), menu))
                .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "菜单未找到。")); // 抛出BusinessException
    }

    @Operation(summary = "创建新食堂菜单", description = "创建一个新的食堂菜单记录。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "201", description = "菜单创建成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误 (如校验失败，请检查请求体)"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @PostMapping
    @PreAuthorize("hasRole('管理员')") // 只有拥有 'ROLE_管理员' 角色的用户才能访问
    public ResponseResult<CanteenMenu> createCanteenMenu(
            @Parameter(description = "食堂菜单创建请求对象 (无需传入 menuId)", required = true)
            @RequestBody @Valid CanteenMenuCreateRequest request) {

        CanteenMenu canteenMenu = new CanteenMenu();
        BeanUtils.copyProperties(request, canteenMenu);

        boolean success = canteenMenuService.save(canteenMenu);
        if (!success) { // 如果保存操作返回false但未抛出异常
            throw new BusinessException(HttpStatusEnum.BAD_REQUEST.getCode(), "食堂菜单创建失败，请稍后重试。"); // 抛出BusinessException
        }
        return ResponseResult.success(HttpStatusEnum.CREATED.getCode(), HttpStatusEnum.CREATED.getMessage(), canteenMenu);
    }

    @Operation(summary = "更新食堂菜单", description = "根据菜单ID更新食堂菜单信息。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "菜单更新成功"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "404", description = "菜单未找到"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @PutMapping("/{id}")
    @PreAuthorize("hasRole('管理员')") // 只有拥有 'ROLE_管理员' 角色的用户才能访问
    public ResponseResult<CanteenMenu> updateCanteenMenu(
            @Parameter(description = "菜单ID", required = true, example = "1") @PathVariable Long id,
            @Parameter(description = "更新后的食堂菜单对象", required = true) @RequestBody @Valid CanteenMenuUpdateRequest request) {

        // 使用Optional简化null检查，如果未找到则抛出业务异常
        CanteenMenu existingMenu = Optional.ofNullable(canteenMenuService.getById(id))
                .orElseThrow(() -> new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "菜单未找到。")); // 抛出BusinessException


        BeanUtils.copyProperties(request, existingMenu);

        boolean success = canteenMenuService.updateById(existingMenu);
        if (!success) { // 如果更新返回false
            throw new BusinessException(HttpStatusEnum.BAD_REQUEST.getCode(), "食堂菜单更新失败，请稍后重试。"); // 抛出BusinessException
        }
        return ResponseResult.success(HttpStatusEnum.SUCCESS.getCode(), HttpStatusEnum.SUCCESS.getMessage(), existingMenu);
    }

    @Operation(summary = "删除食堂菜单", description = "根据菜单ID删除食堂菜单。")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "204", description = "菜单删除成功"),
            @ApiResponse(responseCode = "404", description = "菜单未找到"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('管理员')") // 只有拥有 'ROLE_管理员' 角色的用户才能访问
    public ResponseResult<Void> deleteCanteenMenu(
            @Parameter(description = "菜单ID", required = true, example = "1") @PathVariable Long id) {
        boolean success = canteenMenuService.removeById(id);
        if (!success) { // 如果删除返回false
            throw new BusinessException(HttpStatusEnum.NOT_FOUND.getCode(), "菜单未找到或删除失败。"); // 抛出BusinessException
        }
        return ResponseResult.success(HttpStatusEnum.NO_CONTENT.getCode(), HttpStatusEnum.NO_CONTENT.getMessage(), null);
    }
}
